/*
 *    Copyright (c) 2018-2025, boss All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the boss developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: boss
 */
package com.hopes.bizz.basic.safe.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hopes.bizz.basic.common.constant.FlowConstant;
import com.hopes.bizz.basic.common.constant.FlowDicConstant;
import com.hopes.bizz.basic.common.constant.enums.ParkBasicSysDictEnum;
import com.hopes.bizz.basic.drive.bo.BaseTaskBo;
import com.hopes.bizz.basic.drive.dto.BaseAuditDTO;
import com.hopes.bizz.basic.gis.vo.LicenceProductionVo;
import com.hopes.bizz.basic.safe.dto.BaseLicenceProductionExcelDTO;
import com.hopes.bizz.basic.safe.entity.BaseLicenceProductionEntity;
import com.hopes.bizz.basic.safe.entity.BaseLicenceProductionHandleRecordEntity;
import com.hopes.bizz.basic.safe.mapper.BaseLicenceProductionMapper;
import com.hopes.bizz.basic.safe.service.BaseLicenceProductionHandleRecordService;
import com.hopes.bizz.basic.safe.service.BaseLicenceProductionService;
import com.hopes.bizz.basic.safe.vo.BaseLicenceProductionExcelVO;
import com.hopes.bizz.common.core.validate.ValidatorUtils;
import com.hopes.boss.act.base.FlowServiceImpl;
import com.hopes.boss.act.base.TaskExecute;
import com.hopes.boss.act.enums.FlowTaskHandlerType;
import com.hopes.boss.act.vo.FlowTaskInfo;
import com.hopes.boss.admin.api.resolver.DictResolver;
import com.hopes.boss.admin.api.resolver.enums.AdminDictEnum;
import com.hopes.boss.common.entity.ValidateImportBO;
import com.hopes.boss.common.excel.vo.ErrorMessage;
import com.hopes.boss.common.security.util.SecurityUtils;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 安全生产许可证
 *
 * @author pig
 * @date 2023-11-01 16:44:49
 */
@Service
public class BaseLicenceProductionServiceImpl extends FlowServiceImpl<BaseLicenceProductionMapper, BaseLicenceProductionEntity> implements BaseLicenceProductionService {


    @Autowired
    private BaseLicenceProductionHandleRecordService productionHandleRecordService;

    @Override
    public ValidateImportBO<BaseLicenceProductionExcelDTO> validateImport(List<BaseLicenceProductionExcelDTO> excelDTOList) {
        ValidateImportBO<BaseLicenceProductionExcelDTO> bo = new ValidateImportBO<>();
        List<ErrorMessage> errorMessageList = new ArrayList<>();
        List<BaseLicenceProductionExcelDTO> saveList = new ArrayList<>();
        int successNum = 0;
        int failedNum = 0;
        for (BaseLicenceProductionExcelDTO baseLicenceProductionExcelDTO : excelDTOList) {
            String validateRes = ValidatorUtils.validateEntity(baseLicenceProductionExcelDTO);
            if (StrUtil.isEmpty(validateRes)) {
                successNum++;
                saveList.add(baseLicenceProductionExcelDTO);
            } else {
                failedNum++;
                errorMessageList.add(new ErrorMessage(baseLicenceProductionExcelDTO.getLineNum(), new HashSet<String>() {{
                    add(validateRes);
                }}));
            }
        }
        bo.setErrorMessages(errorMessageList);
        bo.setSaveList(saveList);
        bo.setSuccessNum(successNum);
        bo.setFailedNum(failedNum);
        return bo;
    }

    @Override
    public BaseLicenceProductionEntity importDtoToEntity(BaseLicenceProductionExcelDTO excelDto) {
        BaseLicenceProductionEntity entity = new BaseLicenceProductionEntity();
        BeanUtils.copyProperties(excelDto, entity);
        entity.setOrgId(Long.valueOf(DictResolver.getItemValueByLabel(AdminDictEnum.sys_company, excelDto.getOrgId())));
        entity.setLicenseType(DictResolver.getItemValueByLabel(ParkBasicSysDictEnum.license_type, excelDto.getLicenseType()));
        return entity;
    }

    @Override
    public BaseLicenceProductionExcelVO exportEntityToVo(BaseLicenceProductionEntity entity) {
        BaseLicenceProductionExcelVO excelVO = new BaseLicenceProductionExcelVO();
        BeanUtils.copyProperties(entity, excelVO);
        return excelVO;
    }

    @Override
    public LicenceProductionVo getLicenceProductionInfo() {
        LicenceProductionVo productionGisInfo = new LicenceProductionVo();
        JSONArray pieData = new JSONArray();
        JSONObject barData = new JSONObject();
        List<BaseLicenceProductionEntity> productionEntities = baseMapper.selectList(null);
        // 状态统计
        Map<String, Long> statusMap = productionEntities.stream().collect(Collectors.groupingBy(BaseLicenceProductionEntity::getLicenseStatus, Collectors.counting()));
        statusMap.forEach((k, v) -> {
            JSONObject data = new JSONObject();
            data.put("name", DictResolver.getItemLabelByValue(ParkBasicSysDictEnum.certificate_status, k));
            data.put("value", v);
            pieData.add(data);
        });
        // 类型统计
        Map<String, Long> typeMap = productionEntities.stream().collect(Collectors.groupingBy(BaseLicenceProductionEntity::getLicenseType, Collectors.counting()));
        ArrayList<String> name = new ArrayList<>();
        ArrayList<Long> count = new ArrayList<>();
        barData.put("name",name);
        barData.put("count",count);
        typeMap.forEach((k, v) -> {
            name.add(DictResolver.getItemLabelByValue(ParkBasicSysDictEnum.license_type, k));
            count.add(v);
        });
        productionGisInfo.setBarData(barData);
        productionGisInfo.setPieData(pieData);
        return productionGisInfo;
    }


    @Override
    @GlobalTransactional // 分布式事务注解
    public void handlerAudit(BaseAuditDTO baseAuditDTO) {
        Long id = baseAuditDTO.getId();
        FlowTaskHandlerType flowTaskHandlerType = FlowTaskHandlerType.getFlowTaskHandlerTypeByCode(baseAuditDTO.getHandleResult());
        // 提交工作流
        BaseTaskBo baseTaskBo = new BaseTaskBo()
                .setHandleResultDesc(baseAuditDTO.getHandleResultDesc())
                .setAttachment(baseAuditDTO.getAttachment())
                .setHandleTime(baseAuditDTO.getHandleTime())
                .setSignature(baseAuditDTO.getSignature());
        TaskExecute taskExecute = new TaskExecute.Build()
                .setBusinessKey(id)
                .setFlowTaskHandlerType(flowTaskHandlerType)
                .setBusinessData(baseTaskBo)
                .build();
        executeTask(taskExecute);
    }

    @Override
    @GlobalTransactional // 分布式事务注解
    public void handleSubmit(Long id) {
        TaskExecute taskExecute = new TaskExecute.Build()
                .setBusinessKey(id)
                .setFlowTaskHandlerType(FlowTaskHandlerType.TASK_HANDLE_TYPE_SUBMIT)
                .build();
        executeTask(taskExecute);
    }

    @Override
    public void doCompletedTask(FlowTaskInfo flowTaskInfo, Long id, FlowTaskHandlerType handlerType, Object data) {
        // 提交操作创建当前节点和下一节点
        if (FlowTaskHandlerType.TASK_HANDLE_TYPE_SUBMIT.equals(handlerType)) {
            BaseLicenceProductionHandleRecordEntity startNode = new BaseLicenceProductionHandleRecordEntity();
            startNode.setNodeCode(FlowDicConstant.START);
            startNode.setBusinessId(id);
            startNode.setHandleUserId(SecurityUtils.getUserId());
            startNode.setHandleTime(new Date());
            productionHandleRecordService.save(startNode);
            // 下一节点
            BaseLicenceProductionHandleRecordEntity nextNode = new BaseLicenceProductionHandleRecordEntity();
            nextNode.setNodeCode(flowTaskInfo.getStatus());
            nextNode.setBusinessId(id);
            nextNode.setExecutor(flowTaskInfo.getCandidateStr());
            productionHandleRecordService.save(nextNode);
            // 更新当前纪录为填报中
            lambdaUpdate().set(BaseLicenceProductionEntity::getAuditStatus, FlowDicConstant.IN_REVIEW)
                    .eq(BaseLicenceProductionEntity::getId, id).update();
        } else {
            BaseTaskBo baseTaskBo = (BaseTaskBo) data;
            // 通过 更新上一节点
            BaseLicenceProductionEntity overhaulRecord = getById(id);
            BaseLicenceProductionHandleRecordEntity preRecord = productionHandleRecordService.lambdaQuery()
                    .eq(BaseLicenceProductionHandleRecordEntity::getBusinessId, id)
                    .eq(BaseLicenceProductionHandleRecordEntity::getNodeCode, overhaulRecord.getAuditStatus())
                    .orderByDesc(BaseLicenceProductionHandleRecordEntity::getCreateTime)
                    .select(BaseLicenceProductionHandleRecordEntity::getId)
                    .last("limit 1")
                    .one();
            productionHandleRecordService.lambdaUpdate()
                    .eq(BaseLicenceProductionHandleRecordEntity::getId, preRecord.getId())
                    .set(BaseLicenceProductionHandleRecordEntity::getHandleUserId, SecurityUtils.getUserId())
                    .set(BaseLicenceProductionHandleRecordEntity::getHandleResultDesc, baseTaskBo.getHandleResultDesc())
                    .set(BaseLicenceProductionHandleRecordEntity::getHandleTime, baseTaskBo.getHandleTime())
                    .set(BaseLicenceProductionHandleRecordEntity::getAttachment, baseTaskBo.getAttachment())
                    .set(BaseLicenceProductionHandleRecordEntity::getSignature, baseTaskBo.getSignature())
                    .set(BaseLicenceProductionHandleRecordEntity::getHandleResult, handlerType.getName())
                    .update();
        }
        if (FlowTaskHandlerType.TASK_HANDLE_TYPE_PASS.equals(handlerType)) {
            // 更新当前纪录为审核通过
            lambdaUpdate().set(BaseLicenceProductionEntity::getAuditStatus, FlowDicConstant.PASS)
                    .eq(BaseLicenceProductionEntity::getId, id).update();
        } else if (FlowTaskHandlerType.TASK_HANDLE_TYPE_BACK.equals(handlerType)) {
            // 更新当前纪录为审核通过
            lambdaUpdate().set(BaseLicenceProductionEntity::getAuditStatus, FlowDicConstant.NOT_PASS)
                    .eq(BaseLicenceProductionEntity::getId, id).update();
        }
    }

    @Override
    public void deleteBusiness(Collection<Long> meantimeList) {
        // 删除相关处理纪录
        productionHandleRecordService.remove(Wrappers.lambdaQuery(BaseLicenceProductionHandleRecordEntity.class).in(BaseLicenceProductionHandleRecordEntity::getBusinessId, meantimeList));
    }

    @Override
    public String getFlowDefinitionKey(Long id) {
        return FlowConstant.BASE_LICENCE_PRODUCTION;
    }
}
